From ed3bb05b422100d4937732769d89c0cd394e47a6 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 22 Jul 2014 17:53:38 -0700 Subject: [PATCH] Fix crates with the same name as standard crates The test and bin executables weren't getting the correct --extern flags when tested and built, so the names were conflicting. This passes --extern for the local crate to ensure the right crate is picked up. --- src/cargo/ops/cargo_new.rs | 10 ++--- src/cargo/ops/cargo_rustc/mod.rs | 46 ++++++++++++++------ tests/test_cargo_compile.rs | 25 +++++++++++ tests/test_cargo_test.rs | 74 ++++++++++++++++++++++++++++++++ 4 files changed, 135 insertions(+), 20 deletions(-) diff --git a/src/cargo/ops/cargo_new.rs b/src/cargo/ops/cargo_new.rs index 3039a5e3c..51e8255d4 100644 --- a/src/cargo/ops/cargo_new.rs +++ b/src/cargo/ops/cargo_new.rs @@ -1,12 +1,9 @@ use std::os; use std::io; -use std::io::{fs, File, Command}; +use std::io::{fs, File}; -use ops; -use util::{CargoResult, human, ProcessError, Config, ChainError, process}; +use util::{CargoResult, human, ChainError, process}; use core::shell::MultiShell; -use core::source::Source; -use sources::PathSource; macro_rules! git( ($($a:expr),*) => ({ process("git") $(.arg($a))* .exec_with_output() @@ -18,8 +15,7 @@ pub struct NewOptions<'a> { pub path: &'a str, } -pub fn new(opts: NewOptions, shell: &mut MultiShell) -> CargoResult<()> { - let config = try!(Config::new(shell, false, None, None)); +pub fn new(opts: NewOptions, _shell: &mut MultiShell) -> CargoResult<()> { let path = os::getcwd().join(opts.path); if path.exists() { return Err(human(format!("Destination `{}` already exists", diff --git a/src/cargo/ops/cargo_rustc/mod.rs b/src/cargo/ops/cargo_rustc/mod.rs index bba7072b2..4a17a6129 100644 --- a/src/cargo/ops/cargo_rustc/mod.rs +++ b/src/cargo/ops/cargo_rustc/mod.rs @@ -208,16 +208,16 @@ fn prepare_rustc(package: &Package, target: &Target, crate_types: Vec<&str>, let base = util::process("rustc").cwd(root.clone()); let base = build_base_args(base, target, crate_types.as_slice()); - let target = build_plugin_args(base.clone(), cx, false); - let plugin = build_plugin_args(base, cx, true); - let target = build_deps_args(target, package, cx, false); - let plugin = build_deps_args(plugin, package, cx, true); + let target_cmd = build_plugin_args(base.clone(), cx, false); + let plugin_cmd = build_plugin_args(base, cx, true); + let target_cmd = build_deps_args(target_cmd, target, package, cx, false); + let plugin_cmd = build_deps_args(plugin_cmd, target, package, cx, true); match req { - Target => vec![target], - Plugin => vec![plugin], - PluginAndTarget if cx.config.target().is_none() => vec![target], - PluginAndTarget => vec![target, plugin], + Target => vec![target_cmd], + Plugin => vec![plugin_cmd], + PluginAndTarget if cx.config.target().is_none() => vec![target_cmd], + PluginAndTarget => vec![target_cmd, plugin_cmd], } } @@ -290,8 +290,8 @@ fn build_plugin_args(mut cmd: ProcessBuilder, cx: &Context, return cmd; } -fn build_deps_args(mut cmd: ProcessBuilder, package: &Package, cx: &Context, - plugin: bool) -> ProcessBuilder { +fn build_deps_args(mut cmd: ProcessBuilder, target: &Target, package: &Package, + cx: &Context, plugin: bool) -> ProcessBuilder { let layout = cx.layout(plugin); cmd = cmd.arg("-L").arg(layout.root()); cmd = cmd.arg("-L").arg(layout.deps()); @@ -301,20 +301,40 @@ fn build_deps_args(mut cmd: ProcessBuilder, package: &Package, cx: &Context, cmd = push_native_dirs(cmd, &layout, package, cx, &mut HashSet::new()); for &(_, target) in cx.dep_targets(package).iter() { + cmd = link_to(cmd, target, cx, true); + } + + let mut targets = package.get_targets().iter().filter(|target| { + target.is_lib() && target.get_profile().is_compile() + }); + + if target.is_bin() { + for target in targets { + cmd = link_to(cmd, target, cx, false); + } + } + + return cmd; + + fn link_to(mut cmd: ProcessBuilder, target: &Target, + cx: &Context, is_dep_lib: bool) -> ProcessBuilder { let layout = cx.layout(target.get_profile().is_plugin()); for filename in cx.target_filenames(target).iter() { let mut v = Vec::new(); v.push_all(target.get_name().as_bytes()); v.push(b'='); - v.push_all(layout.deps().as_vec()); + if is_dep_lib { + v.push_all(layout.deps().as_vec()); + } else { + v.push_all(layout.root().as_vec()); + } v.push(b'/'); v.push_all(filename.as_bytes()); cmd = cmd.arg("--extern").arg(v.as_slice()); } + return cmd; } - return cmd; - fn push_native_dirs(mut cmd: ProcessBuilder, layout: &layout::LayoutProxy, pkg: &Package, cx: &Context, visited: &mut HashSet) -> ProcessBuilder { diff --git a/tests/test_cargo_compile.rs b/tests/test_cargo_compile.rs index eabf75ac4..cd88adab5 100644 --- a/tests/test_cargo_compile.rs +++ b/tests/test_cargo_compile.rs @@ -1270,3 +1270,28 @@ test!(bad_cargo_toml_in_target_dir { assert_that(p.cargo_process("cargo-build"), execs().with_status(0)); assert_that(process(p.bin("foo")), execs().with_status(0)); }) + +test!(lib_with_standard_name { + let p = project("foo") + .file("Cargo.toml", r#" + [package] + name = "syntax" + version = "0.0.1" + authors = [] + "#) + .file("src/lib.rs", " + pub fn foo() {} + ") + .file("src/main.rs", " + extern crate syntax; + fn main() { syntax::foo() } + "); + + assert_that(p.cargo_process("cargo-build"), + execs().with_status(0) + .with_stdout(format!("\ +{compiling} syntax v0.0.1 (file:{dir}) +", + compiling = COMPILING, + dir = p.root().display()).as_slice())); +}) diff --git a/tests/test_cargo_test.rs b/tests/test_cargo_test.rs index 829ece783..769c82381 100644 --- a/tests/test_cargo_test.rs +++ b/tests/test_cargo_test.rs @@ -390,3 +390,77 @@ test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured"; assert!(out == format!("{}\n\n{}\n\n\n{}\n\n", head, bin, lib).as_slice() || out == format!("{}\n\n{}\n\n\n{}\n\n", head, lib, bin).as_slice()); }) + +test!(lib_with_standard_name { + let p = project("foo") + .file("Cargo.toml", r#" + [package] + name = "syntax" + version = "0.0.1" + authors = [] + + [[lib]] + name = "syntax" + test = false + "#) + .file("src/lib.rs", " + pub fn foo() {} + ") + .file("tests/test.rs", " + extern crate syntax; + + #[test] + fn test() { syntax::foo() } + "); + + assert_that(p.cargo_process("cargo-test"), + execs().with_status(0) + .with_stdout(format!("\ +{compiling} syntax v0.0.1 (file:{dir}) + +running 1 test +test test ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured\n\n\ + ", + compiling = COMPILING, + dir = p.root().display()).as_slice())); +}) + +test!(lib_with_standard_name2 { + let p = project("foo") + .file("Cargo.toml", r#" + [package] + name = "syntax" + version = "0.0.1" + authors = [] + + [[lib]] + name = "syntax" + test = false + "#) + .file("src/lib.rs", " + pub fn foo() {} + ") + .file("src/main.rs", " + extern crate syntax; + + fn main() {} + + #[test] + fn test() { syntax::foo() } + "); + + assert_that(p.cargo_process("cargo-test"), + execs().with_status(0) + .with_stdout(format!("\ +{compiling} syntax v0.0.1 (file:{dir}) + +running 1 test +test test ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured\n\n\ + ", + compiling = COMPILING, + dir = p.root().display()).as_slice())); +}) -- 2.30.2